package NewTmas.TableModels;

import taskmaster.auth.User;
import taskmaster.job.Job;
import taskmaster.job.JobAllTasksCollection;
import taskmaster.job.Task;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: abhatnag
 * Date: 7/7/11
 * Time: 1:46 PM
 * Table model for the job states table
 */
public class JobTableModel extends AbstractTableModel
{

    User user;
    Connection connection;
    Date date;
    Object[][] data;
    String[] columnNames;
    HashMap<String, Integer> completedTasksbyJob = new HashMap<String, Integer>();
    HashMap<String, Integer> failedTasksbyJob = new HashMap<String, Integer>();
    HashMap<String, Integer> totalTaskCount = new HashMap<String, Integer>();
    Hashtable allRolesHash;

    public JobTableModel(User user, Date date, Hashtable allRolesHash)
    {
        this.user = user;
        this.connection = user.getConnection();
        this.date = date;
        this.allRolesHash = allRolesHash;
        populateTable();

    }

    public void populateTable()
    {
        columnNames = new String[]{"Job_Tag", "Run_Date", "Start_Time", "End_Time", "State", "Description", "Config", "Condition_cmd", "#Succeeded Tasks", "#Failed Tasks", "% Completed", "Roles"};
        Job[] jobs = getJobInfo();
        getTotalTasksCount();
        failedTasksbyJob();
        completedTasksbyJob();
        data = new Object[jobs.length][columnNames.length];
        int succeeded = 0;


        for (int i = 0; i < jobs.length; i++)
        {
            StringBuffer allroleString = new StringBuffer();
            JobAllTasksCollection alltc = new JobAllTasksCollection(connection, jobs[i].getJob_tag(), "GraphViz");

            HashSet<String> rolesSet = new HashSet<String>();

            for (Task t : alltc.alljobTasks)
            {
                rolesSet.add(allRolesHash.get(String.valueOf(t.getRoleId())).toString());
            }
            String[] roles = new String[rolesSet.size()];
            roles = rolesSet.toArray(roles);

            Arrays.sort(roles);

            for (String str : roles)
            {
                allroleString.append(str);
                allroleString.append(",");
            }

            data[i][0] = jobs[i].getJob_tag();
            data[i][1] = jobs[i].getRun_date();
            data[i][2] = jobs[i].getStart_time();
            data[i][3] = jobs[i].getEnd_time();
            data[i][4] = jobs[i].getState();
            data[i][5] = jobs[i].getDescription();
            data[i][6] = jobs[i].getConfig();

            if (jobs[i].getCmd() == null)
            {
                data[i][7] = "";
            } else
            {
                data[i][7] = jobs[i].getCmd();
            }
            if (completedTasksbyJob.containsKey(jobs[i].getJob_tag()))
            {
                data[i][8] = completedTasksbyJob.get(jobs[i].getJob_tag());
                succeeded = completedTasksbyJob.get(jobs[i].getJob_tag());
            } else
            {
                data[i][8] = "";
            }

            if (failedTasksbyJob.containsKey(jobs[i].getJob_tag()))
            {
                data[i][9] = failedTasksbyJob.get(jobs[i].getJob_tag());
            } else
            {
                data[i][9] = "";
            }
            if (totalTaskCount.containsKey(jobs[i].getJob_tag()))
            {
                data[i][10] = ((float) succeeded / (totalTaskCount.get(jobs[i].getJob_tag()))) * 100;
            } else
            {
                data[i][10] = 0;
            }
            data[i][11] = allroleString;
        }
    }


    public Job[] getJobInfo()
    {

        Statement stmt = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("MMM-dd-yyyy");
        ResultSet rs1 = null;

        HashSet<Job> jobSet = new HashSet<Job>();
        try
        {
            stmt = connection.createStatement();
            rs1 = stmt.executeQuery("select T.job_tag,T.run_date,T.start_time,T.end_time,T.state,A.description,A.config,A.condition_cmd from tms.job_states T ,tms.jobs A where A.job_tag=T.job_tag and T.run_date='" + dateFormat.format(date) + "'");


            while (rs1.next())
            {

                jobSet.add(new Job(rs1.getString("JOB_TAG"), rs1.getDate("RUN_DATE"), rs1.getTime("START_TIME"), rs1.getTime("END_TIME"),
                        rs1.getString("STATE"), rs1.getString("DESCRIPTION"), rs1.getString("CONFIG"), rs1.getString("CONDITION_CMD")
                ));
            }
            rs1.close();
            stmt.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error retrieving job states values from the database: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }

        Job[] jobarray = new Job[jobSet.size()];
        jobarray = jobSet.toArray(jobarray);

        return jobarray;
    }


    public void completedTasksbyJob()
    {
        Statement stmt = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("MMM-dd-yyyy");
        ResultSet rs1 = null;

        try
        {
            stmt = connection.createStatement();
            rs1 = stmt.executeQuery("select job_tag,count(distinct task_tag) as Completed from tms.task_states A,TMS.TASK_STATUSES B  where A.STATUS_ID=B.STATUS_ID AND B.CATEGORY = 'completed' and run_date='" + dateFormat.format(date) + "'group by job_tag");

            while (rs1.next())
            {
                completedTasksbyJob.put(rs1.getString("JOB_TAG"), rs1.getInt("COMPLETED"));
            }
            rs1.close();
            stmt.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error retrieving the completed job states from the database: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }

    }


    public void failedTasksbyJob()
    {
        Statement stmt = null;
        SimpleDateFormat dateFormat = new SimpleDateFormat("MMM-dd-yyyy");
        ResultSet rs1 = null;
        try
        {
            stmt = connection.createStatement();
            rs1 = stmt.executeQuery("select job_tag,count(distinct task_tag) as Failed from tms.task_states A,TMS.TASK_STATUSES B  where A.STATUS_ID=B.STATUS_ID AND B.CATEGORY = 'error' and run_date='" + dateFormat.format(date) + "'group by job_tag");

            while (rs1.next())
            {
                failedTasksbyJob.put(rs1.getString("JOB_TAG"), rs1.getInt("Failed"));
            }
            rs1.close();
            stmt.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error retrieving the failed job states from the database: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }

    }

    public void getTotalTasksCount()
    {
        Statement stmt = null;
        ResultSet rs1 = null;
        try
        {
            stmt = connection.createStatement();
            rs1 = stmt.executeQuery("select job_tag,count(distinct task_tag) as total from tms.tasks group by job_tag");

            while (rs1.next())
            {
                totalTaskCount.put(rs1.getString("JOB_TAG"), rs1.getInt("total"));
            }
            rs1.close();
            stmt.close();
        } catch (SQLException e)
        {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error retrieving the total job task count from the database: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }

    }


    public int getRowCount()
    {
        return data.length;
    }

    public int getColumnCount()
    {
        return columnNames.length;
    }

    public Object getValueAt(int rowIndex, int columnIndex)
    {
        return data[rowIndex][columnIndex];
    }

    public String getColumnName(int col)
    {
        return columnNames[col];
    }

}
